/*
 * Copyright 2010 - Jeremie Brebec
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package org.jb.sharedbills.client.stores;

import java.util.Collection;

import org.jb.sharedbills.shared.model.Event;
import org.jb.sharedbills.shared.model.Group;
import org.jb.sharedbills.shared.model.notification.CollectionNotification;
import org.jb.sharedbills.shared.model.notification.Notification;
import org.jb.sharedbills.shared.model.notification.NotificationListener;

import com.extjs.gxt.ui.client.data.BeanModel;
import com.extjs.gxt.ui.client.data.BeanModelFactory;
import com.extjs.gxt.ui.client.data.BeanModelLookup;
import com.extjs.gxt.ui.client.store.ListStore;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;

public class GroupStore extends ListStore<BeanModel> implements NotificationListener {

	/**
	 * 
	 * @param members
	 */
	@Inject
	public GroupStore( EventLoader eventLoader ) {
		eventLoader.load( new AsyncCallback<Event>() {
			
			@Override
			public void onSuccess(Event result) {
				event = result;
				event.getGroups().addListener(GroupStore.this);
				addGroups(event.getGroups());
			}
			
			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}
		});
	}

	/**
	 * 
	 */
	public void close() {
		event.getGroups().removeListener(this);
	}
	
	/**
	 * 
	 */
	private void addGroups( Collection<Group> Groups ) {		
		for( Group Group : Groups ) {
			addGroup( Group );
		}
	}
	
	/**
	 * 
	 */
	private void removeGroups( Collection<Group> Groups ) {		
		for( Group Group : Groups ) {
			removeGroup( Group );
		}
	}
	
	/**
	 * 
	 * @param member
	 */
	private void addGroup( Group Group ) {
		add( groupFactory.createModel(Group) );
	}
	
	/**
	 * 
	 * @param member
	 */
	private void removeGroup( Group group ) {
		BeanModel b = getBean( group );
		if (b != null)
			remove( b );
	}
	
	
	
	/**
	 * 
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void handle(Notification notification) {
		if (notification.getSender() == event) {
			if ("groups".equals( notification.getProperty())) {
				if (notification instanceof CollectionNotification<?>) {
					CollectionNotification<Group> colNotif = (CollectionNotification<Group>)notification;
					
					addGroups( (Collection<Group>)colNotif.getAdded() );
					removeGroups( (Collection<Group>)colNotif.getRemoved() );
				}
			}
		}
		
		if (notification.getSender() instanceof Group) {
			//if (notification instanceof PropertyChangeNotification<?>) {
				
				BeanModel b = getBean( (Group)notification.getSender() );
				if (b != null)
					update(b);
			//}
		}
	}
	
	/**
	 * 
	 * @param m
	 * @return
	 */
	public BeanModel getBean(Group m) {
		for( BeanModel b : getModels() ) {
			if (b.getBean() == m) {
				return b;
			}
		}
		
		return null;
	}
	
	/**
	 * 
	 * @return
	 */
	public Event getEvent() {
		return event;
	}
	
	private Event event;
	public static final  BeanModelFactory groupFactory = BeanModelLookup.get().getFactory(Group.class);
	

}